using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;

internal class SKHook
{
    private HookProc m_KeyboardHookProcedure;
    private readonly byte[] m_KeyState = new byte[0x100];
    private HookProc m_MouseHookProcedure;
    private IntPtr m_pKeyboardHook = IntPtr.Zero;
    private IntPtr m_pMouseHook = IntPtr.Zero;

    public event KeyEventHandler OnKeyDown;

    public event KeyPressEventHandler OnKeyPress;

    public event KeyEventHandler OnKeyUp;

    public event MouseUpdateEventHandler OnMouseUpdate;

    public SKHook()
    {
        Win32API.GetKeyboardState(this.m_KeyState);
    }

    public bool InstallHook()
    {
        IntPtr hINSTANCE = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule);
        if (this.m_pMouseHook == IntPtr.Zero)
        {
            this.m_MouseHookProcedure = new HookProc(this.MouseHookProc);
            this.m_pMouseHook = Win32API.SetWindowsHookEx(WH_Codes.WH_MOUSE_LL, this.m_MouseHookProcedure, hINSTANCE, 0);
            if (this.m_pMouseHook == IntPtr.Zero)
            {
                this.UnInstallHook();
                return false;
            }
        }
        if (this.m_pKeyboardHook == IntPtr.Zero)
        {
            this.m_KeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
            this.m_pKeyboardHook = Win32API.SetWindowsHookEx(WH_Codes.WH_KEYBOARD_LL, this.m_KeyboardHookProcedure, hINSTANCE, 0);
            if (this.m_pKeyboardHook == IntPtr.Zero)
            {
                this.UnInstallHook();
                return false;
            }
        }
        return true;
    }

    private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)
    {
        if ((nCode >= 0) && (((this.OnKeyDown != null) || (this.OnKeyPress != null)) || (this.OnKeyUp != null)))
        {
            KeyboardHookStruct struct2 = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            if ((this.OnKeyDown != null) && ((wParam == 0x100) || (wParam == 260)))
            {
                KeyEventArgs e = new KeyEventArgs((Keys) struct2.VKCode);
                this.OnKeyDown(this, e);
            }
            if ((this.OnKeyPress != null) && (wParam == 0x101))
            {
                byte[] lpwTransKey = new byte[2];
                if (Win32API.ToAscii(struct2.VKCode, struct2.ScanCode, this.m_KeyState, lpwTransKey, struct2.Flags) == 1)
                {
                    KeyPressEventArgs args2 = new KeyPressEventArgs((char) lpwTransKey[0]);
                    this.OnKeyPress(this, args2);
                }
            }
            if ((this.OnKeyUp != null) && ((wParam == 0x101) || (wParam == 0x105)))
            {
                KeyEventArgs args3 = new KeyEventArgs((Keys) struct2.VKCode);
                this.OnKeyUp(this, args3);
            }
        }
        return Win32API.CallNextHookEx(this.m_pKeyboardHook, nCode, wParam, lParam);
    }

    private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
    {
        if (((nCode >= 0) && (this.OnMouseUpdate != null)) && ((wParam == 0x200) || (wParam == 0x20a)))
        {
            MouseHookStruct struct2 = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
            this.OnMouseUpdate(struct2.Point.X, struct2.Point.Y);
        }
        return Win32API.CallNextHookEx(this.m_pMouseHook, nCode, wParam, lParam);
    }

    public bool UnInstallHook()
    {
        bool flag = true;
        if (this.m_pMouseHook != IntPtr.Zero)
        {
            flag = Win32API.UnhookWindowsHookEx(this.m_pMouseHook) && flag;
            this.m_pMouseHook = IntPtr.Zero;
        }
        if (this.m_pKeyboardHook != IntPtr.Zero)
        {
            flag = Win32API.UnhookWindowsHookEx(this.m_pKeyboardHook) && flag;
            this.m_pKeyboardHook = IntPtr.Zero;
        }
        return flag;
    }
}

